package org.ant.gui.panes;

import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import org.ant.ctrl.CodesManager;
import org.ant.gui.AntFrame;
import org.ant.gui.layout.GBC;
import org.ant.parser.ASTStart;
import org.ant.parser.Node;
import org.ant.util.Code;

public class ClassTreePane extends JPanel {

	public static final String NAME = "Class Tree";

	private JTree tree;
	private DefaultMutableTreeNode node;
	private Node astNode;

	public ClassTreePane() {
		super();
		init();
		loadComponent();
	}

	protected void init() {
		setName(NAME);
	}

	protected void loadComponent() {
		setLayout(new GridBagLayout());
		JScrollPane sp = new JScrollPane(getTree());
		sp
				.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		add(sp, new GBC(0, 0).setWeight(1, 1).setFill(GBC.BOTH));
		update();
	}

	public JTree getTree() {
		Code code = CodesManager.getInstane().getCurrentCode();
		if (tree == null && code != null) {
			node = new DefaultMutableTreeNode(code.getPath());
			tree = new JTree(node);
			MouseListener ml = new MouseAdapter() {
				public void mouseClicked(MouseEvent event) {
					int selRow = tree.getRowForLocation(event.getX(), event
							.getY());
					TreePath selPath = tree.getPathForLocation(event.getX(),
							event.getY());
					//if (selRow != -1) {
						DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree
								.getLastSelectedPathComponent();
						Node selNode = nodeVisit(astNode, node, selectedNode);
						setSelectedNode(selNode);
					//}
				}
			};
			tree.addMouseListener(ml);
		}
		return tree;
	}

	private void setSelectedNode(Node selNode) {
		System.err.println("TAC Update" + selNode.toString());
		CodesManager.getInstane().getCurrentCode().setSelNode(selNode);
		AntFrame.getInstance().getAssTabbedPane().getTACPane().update();
	}

	private Node nodeVisit(Node node, TreeNode treeNode, TreeNode selNode) {

		if (treeNode.equals(selNode)) {
			return node;
		} else {
			for (int i = 0; i < treeNode.getChildCount(); i++) {
				//System.out.println(node.jjtGetChild(i).toString() + " ! "
				//		+ treeNode.getChildAt(i).toString() + " !! "
				//		+ selNode.toString());
				Node tnode = nodeVisit(node.jjtGetChild(i), treeNode.getChildAt(i),
						selNode);
				if(tnode != null){
					return tnode;
				}
			}
		}
		return null;
	}

	public void update() {
		try{
			Code code = CodesManager.getInstane().getCurrentCode();
			if (code != null && !code.isNew()) {
				ASTStart ast = code.getAst();
				tree.setVisible(false);
				node.setUserObject(code.getPath());
				node.removeAllChildren();
				astNode = ast;
				visit(astNode.jjtGetChild(0), node);
				tree.repaint();
				tree.setVisible(true);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	private void visit(Node node, DefaultMutableTreeNode treeNode) {
		DefaultMutableTreeNode child = new DefaultMutableTreeNode(node
				.toString());
		treeNode.add(child);
		for (int i = 0; i < node.jjtGetNumChildren(); i++) {
			visit(node.jjtGetChild(i), child);
		}
	}
}
